package org.digitarts.rtms.tracing;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

public class TracerFactory
{

	public static final String				ITRACER_CLASS_NAME_PROPERTY	= "itracer.class.name";
	public static final String				ITRACER_KEY					= "itracer.key";
	protected static Map<String, ITracer>	tracers						= new ConcurrentHashMap<String, ITracer>();

	public static ITracer getInstance()
	{
		try
		{
			String className = System.getProperty(ITRACER_CLASS_NAME_PROPERTY);
			if (className == null)
				className = NullTracer.class.getName();
			String cacheKey = "DEFAULT";
			if (cacheKey != null)
			{
				// Check the cache and see if the ITracer has alreayd been created.
				if (tracers.containsKey(cacheKey))
					return tracers.get(cacheKey);
			}
			// If the ITracer has not been created yet, create it.
			Class<?> itracerClass = Class.forName(className, true, ITracer.class.getClassLoader());
			Constructor<?> ctor = itracerClass.getConstructor();
			ITracer tracer = (ITracer) ctor.newInstance();
			if (cacheKey != null)
			{
				// if a cache key has been provided, cache the itracer.
				tracers.put(cacheKey, tracer);
			}
			return tracer;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new InstantiationError("Failed to create ITracer:" + e);
		}
	}

	public static ITracer getInstance(Properties p) throws InstantiationError
	{
		try
		{
			String className = p.getProperty(ITRACER_CLASS_NAME_PROPERTY);
			String cacheKey = p.getProperty(ITRACER_KEY);
			if (cacheKey != null)
			{
				// Check the cache and see if the ITracer has alreayd been created.
				if (tracers.containsKey(cacheKey))
					return tracers.get(cacheKey);
			}
			// If the ITracer has not been created yet, create it.
			Class<?> itracerClass = Class.forName(className, true, ITracer.class.getClassLoader());
			Constructor<?> ctor = itracerClass.getConstructor(Properties.class);
			ITracer tracer = (ITracer) ctor.newInstance(p);
			if (cacheKey != null)
			{
				// if a cache key has been provided, cache the itracer.
				tracers.put(cacheKey, tracer);
			}
			return tracer;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new InstantiationError("Failed to create ITracer:" + e);
		}
	}

	public static ITracer getInstance(String cacheKey)
	{
		if (tracers.containsKey(cacheKey))
			return tracers.get(cacheKey);
		else
			throw new RuntimeException("ITracer not found in cache under cache key [" + cacheKey + "]");
	}
}
